﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;

namespace DispatchingTelephonePOC
{
    public static class WCFHelper
    {
        // 创建并返回指定类型的双工 WCF 客户端实例
        public static T CreateDuplexClient<T, TCallback>(string endpointAddress, TCallback callbackInstance) where T : class
        {
            // 创建基于通道工厂的双工客户端
            NetTcpBinding netTcpBinding = new NetTcpBinding();

            // 设置超时时间（以秒为单位）
            netTcpBinding.SendTimeout = TimeSpan.FromSeconds(30); // 发送超时
            netTcpBinding.ReceiveTimeout = TimeSpan.FromSeconds(30); // 接收超时
            netTcpBinding.OpenTimeout = TimeSpan.FromSeconds(30); // 打开连接超时
            netTcpBinding.CloseTimeout = TimeSpan.FromSeconds(30); // 关闭连接超时

            // 设置安全模式为 None，如果需要加密通信可根据需求调整
            netTcpBinding.Security.Mode = SecurityMode.None;

            // 设置传输模式为 Buffered，可以根据需求选择 Streamed
            netTcpBinding.TransferMode = TransferMode.Buffered;

            // 设置最大接收消息大小为 10MB
            netTcpBinding.MaxReceivedMessageSize = 10485760; // 10MB in bytes

            // 设置最大缓冲池大小为 524288 bytes (512KB)
            netTcpBinding.MaxBufferPoolSize = 524288;

            // 设置读取配额
            netTcpBinding.ReaderQuotas.MaxStringContentLength = 8192;
            netTcpBinding.ReaderQuotas.MaxArrayLength = 16384;

            var endpoint = new EndpointAddress(endpointAddress);
            var context = new InstanceContext(callbackInstance);
            DuplexChannelFactory<T> factory = new DuplexChannelFactory<T>(context, netTcpBinding, endpoint);
            foreach (OperationDescription op in factory.Endpoint.Contract.Operations)
            {
                DataContractSerializerOperationBehavior dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>() as DataContractSerializerOperationBehavior;
                if (dataContractBehavior != null)
                {
                    dataContractBehavior.MaxItemsInObjectGraph = Int32.MaxValue;
                }
            }
            // 创建和返回双工客户端实例
            return factory.CreateChannel();
        }

        // 关闭 WCF 客户端实例
        public static void CloseClient<T>(T client) where T : ICommunicationObject
        {
            try
            {
                if (client != null && client.State != CommunicationState.Closed)
                {
                    client.Close();
                }
            }
            catch (CommunicationException)
            {
                if (client != null && client.State != CommunicationState.Closed)
                {
                    client.Abort();
                }
            }
            catch (TimeoutException)
            {
                if (client != null && client.State != CommunicationState.Closed)
                {
                    client.Abort();
                }
            }
            catch (Exception)
            {
                if (client != null && client.State != CommunicationState.Closed)
                {
                    client.Abort();
                }
                throw;
            }
        }
    }
}
